package com.oly.cms.admin.service.impl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;

import com.oly.cms.admin.mapper.CmsColumnMapper;
import com.oly.cms.admin.service.ICmsColumnService;
import com.oly.cms.common.constant.CmsCacheConstant;
import com.oly.cms.common.domain.entity.CmsColumn;
import com.oly.cms.common.enums.ColumnNodeTypeEnums;
import com.oly.cms.common.enums.NodeTypeEnums;
import com.oly.cms.common.event.CacheWebRefreshAllEvent;
import com.oly.cms.common.model.properties.OlyCmsConfigProperties;
import com.oly.cms.query.mapper.ColumnSearchMapper;
import com.grace.common.constant.UserConstants;
import com.grace.common.exception.ServiceException;
import com.grace.system.service.impl.SysSearchConfigServiceImpl;

@Service
public class CmsColumnServiceImpl implements ICmsColumnService {
	@Autowired
	private CmsColumnMapper columnMapper;

	@Autowired
	private ColumnSearchMapper columnSearchMapper;

	@Autowired
	private ApplicationEventPublisher app;

	@Autowired
	private SysSearchConfigServiceImpl configService;

	@Override
	public int insertCmsColumn(CmsColumn cmsColumn) {
		int re = 0;
		if (!checkColumnNameUnique(cmsColumn)) {
			throw new ServiceException("当前目录下'" + cmsColumn.getColumnName() + "'菜单名称已存在");
		} else if (cmsColumn.getParentId() == 0) {
			cmsColumn.setAncestors("0");
		} else {
			CmsColumn ccj = selectCmsColumnById(cmsColumn.getParentId());
			if (ccj == null || NodeTypeEnums.LEAF.ordinal() == ColumnNodeTypeEnums.valueOf(ccj.getNodeType())
					.getNodeTypeEnum().ordinal()) {
				throw new ServiceException("菜单插入点不存在或非目录!");
			} else {
				cmsColumn.setAncestors(ccj.getAncestors() + "," + cmsColumn.getParentId());
			}
		}
		re = columnMapper.insertCmsColumn(cmsColumn);
		app.publishEvent(new CacheWebRefreshAllEvent(this, CmsCacheConstant.MENU_CACHE_KEY_PREFIX));
		return re;
	}

	/**
	 * 更新栏目
	 * 基本参数验证
	 * 不能选择自己为父节点
	 * 存在子节点,不允许修改为叶子节点
	 * 验证当前目录下菜单名字
	 * 不允许将父节点移动到子节点
	 * 
	 * @param cmsColumn
	 * @return
	 */
	@Override
	public int updateCmsColumn(CmsColumn cmsColumn) {
		if (cmsColumn.getParentId() == cmsColumn.getColumnId()) {
			throw new ServiceException("不能选择自己为父节点");
		} else if (NodeTypeEnums.LEAF.ordinal() == ColumnNodeTypeEnums.valueOf(cmsColumn.getNodeType())
				.getNodeTypeEnum().ordinal()
				&& columnMapper.selectNumParent(cmsColumn.getColumnId()) > 0) {
			throw new ServiceException("存在子节点,不允许修改节点类型");
		} else if (!checkColumnNameUnique(cmsColumn)) {
			throw new ServiceException("当前目录下'" + cmsColumn.getColumnName() + "'菜单名称已存在");
		} else if (cmsColumn.getParentId().longValue() == 0) {
			cmsColumn.setAncestors("0");
		} else {
			CmsColumn ccj = selectCmsColumnById(cmsColumn.getParentId());
			if (ccj == null || NodeTypeEnums.LEAF.ordinal() == ColumnNodeTypeEnums.valueOf(ccj.getNodeType())
					.getNodeTypeEnum().ordinal()) {
				throw new ServiceException("菜单更新点不存在或非目录!");
			} else {
				cmsColumn.setAncestors(ccj.getAncestors() + "," + cmsColumn.getParentId());
			}
		}
		int re = columnMapper.updateCmsColumn(cmsColumn);
		CmsColumn cColumn = new CmsColumn();
		cColumn.setUpdateBy(cmsColumn.getUpdateBy());
		cColumn.setAncestors(cmsColumn.getAncestors() + "," + cmsColumn.getColumnId());
		cColumn.setParentId(cmsColumn.getColumnId());
		updateChildNode(cColumn);
		updateChildColumnVisible(cmsColumn);
		app.publishEvent(new CacheWebRefreshAllEvent(this, CmsCacheConstant.MENU_CACHE_KEY_PREFIX));
		return re;
	}

	@Override
	public List<CmsColumn> listCmsColumnById(Long parentId) {
		CmsColumn cmsColumn = new CmsColumn();
		cmsColumn.setColumnId(parentId);
		return columnSearchMapper.listCmsColumns(cmsColumn);
	}

	@Override
	public List<CmsColumn> listCmsColumn(CmsColumn cmsColumn) {
		return columnSearchMapper.listCmsColumns(cmsColumn);
	}

	@Override
	public boolean checkColumnNameUnique(CmsColumn cmsColumn) {
		Long columnId = cmsColumn.getColumnId() == null ? -1L : cmsColumn.getColumnId();
		CmsColumn checkColumn = columnSearchMapper.checkColumnNameUnique(cmsColumn);
		if (checkColumn == null || checkColumn.getColumnId().longValue() == columnId.longValue()) {
			return UserConstants.UNIQUE;
		}
		return UserConstants.NOT_UNIQUE;
	}

	@Override
	public CmsColumn selectCmsColumnById(Long columnId) {

		return columnSearchMapper.selectCmsColumnById(columnId);
	}

	@Override
	public int deleteCmsColumnById(Long columnId) {
		if (columnMapper.selectNumParent(columnId) > 0) {
			throw new ServiceException("存在子节点,不允许删除!");
		}
		int re = columnMapper.deleteCmsColumnById(columnId);
		app.publishEvent(new CacheWebRefreshAllEvent(this, CmsCacheConstant.MENU_CACHE_KEY_PREFIX));
		return re;
	}

	@Override
	public int updateChildColumnVisible(CmsColumn c) {
		int re = 0;
		if ("true".equals(configService.selectConfigDefaultValue(OlyCmsConfigProperties.CMS_CONFIG_GROUP.defaultValue(),
				OlyCmsConfigProperties.COLUMN_UPDATE_CHILD))) {
			re = columnMapper.updateChildColumnVisible(c);
		}
		app.publishEvent(new CacheWebRefreshAllEvent(this, CmsCacheConstant.MENU_CACHE_KEY_PREFIX));
		return re;
	}

	/**
	 * 根据父节点的ID获取所有子节点
	 * 
	 * @param list     分类表
	 * @param parentId 传入的父节点ID
	 * @return String
	 */
	public List<CmsColumn> getChildPerms(List<CmsColumn> list, long parentId) {
		List<CmsColumn> returnList = new ArrayList<CmsColumn>();
		for (Iterator<CmsColumn> iterator = list.iterator(); iterator.hasNext();) {
			CmsColumn t = (CmsColumn) iterator.next();
			// 一、根据传入的某个父节点ID,遍历该父节点的所有子节点
			if (t.getParentId() == parentId) {
				recursionFn(list, t);
				returnList.add(t);
			}
		}
		return returnList;
	}

	/**
	 * 递归列表
	 * 
	 * @param list
	 * @param t
	 */
	private void recursionFn(List<CmsColumn> list, CmsColumn t) {
		// 得到子节点列表
		List<CmsColumn> childList = getChildList(list, t);
		// 添加子节点列表
		t.setChildList(childList);
		for (CmsColumn tChild : childList) {
			if (hasChild(list, tChild)) {
				// 判断是否有子节点
				Iterator<CmsColumn> it = childList.iterator();
				while (it.hasNext()) {
					CmsColumn n = (CmsColumn) it.next();
					recursionFn(list, n);
				}
			}
		}
	}

	/**
	 * 得到子节点列表
	 */
	private List<CmsColumn> getChildList(List<CmsColumn> list, CmsColumn t) {
		List<CmsColumn> tlist = new ArrayList<CmsColumn>();
		Iterator<CmsColumn> it = list.iterator();
		while (it.hasNext()) {
			CmsColumn n = (CmsColumn) it.next();
			if (n.getParentId().longValue() == t.getColumnId().longValue()) {
				tlist.add(n);
			}
		}
		return tlist;
	}

	/**
	 * 判断是否有子节点
	 */
	private boolean hasChild(List<CmsColumn> list, CmsColumn t) {
		return getChildList(list, t).size() > 0 ? true : false;
	}

	private void updateChildNode(CmsColumn cmsColumn) {
		if (updateChildColumnAncestor(cmsColumn) > 0) {
			List<Long> lis = listColumnIdsById(cmsColumn.getParentId());
			if (lis != null) {
				for (int i = 0; i < lis.size(); i++) {
					cmsColumn.setAncestors(cmsColumn.getAncestors() + "," + lis.get(i));
					cmsColumn.setParentId(lis.get(i));
					updateChildNode(cmsColumn);
				}
			}
		}
	}

	/**
	 * 根据父亲Id修改Ancestors 根据父亲Id获取子元素子节点，循环遍历
	 * 
	 * @param columnId
	 * @return
	 */
	private List<Long> listColumnIdsById(Long columnId) {
		return columnMapper.listColumnIdsById(columnId);
	}

	private int updateChildColumnAncestor(CmsColumn cmsColumn) {

		return columnMapper.updateChildColumnAncestor(cmsColumn);
	}

}
